#ifndef _SDRAM_DDR_DP_DEVICE_H
#define _SDRAM_DDR_DP_DEVICE_H

#include "SDRAM_DDR_DP_device_if.h"

//#define DEBUG_SDRAM_DDR_DP

const unsigned PORT_NUM = 2;

class SDRAM_DDR_DP_device
: public sc_module
, public SDRAM_DDR_DP_device_if
{
public:
	sc_in_clk CLK;
	sc_in<bool> RSTn;

	const bool
	SDRAM_refresh(unsigned	port_id_,
				  bool		refresh_type_);

	const bool
	SDRAM_row_activate(unsigned		port_id_,
					   unsigned		rank_sel_,
					   unsigned		bank_sel_,
					   SDRAM_addr_t	row_addr_);

	const bool
	SDRAM_read_command(unsigned		port_id_,
					   unsigned		rank_sel_,
					   unsigned		bank_sel_,
					   SDRAM_addr_t	col_addr_,
					   bool			auto_precharge_);

	const bool
	SDRAM_write_command(unsigned		port_id_,
						unsigned		rank_sel_,
						unsigned		bank_sel_,
						SDRAM_addr_t	col_addr_,
						bool			auto_precharge_);

	const bool
	SDRAM_precharge(unsigned	port_id_,
					unsigned	rank_sel_,
					unsigned	bank_sel_,
					bool		precharge_all_);

	const bool
	SDRAM_DDR_mode_register_set(unsigned		port_id_,
								unsigned		EMRS_num_,
								unsigned short	EMRS_code_);

	const SDRAM_DDR_data_t
	SDRAM_DDR_read_data(unsigned	port_id_,
						unsigned	rank_sel_,
						unsigned	bank_sel_,
						unsigned	current_burst_,
						bool		direct_access_);

	const bool
	SDRAM_DDR_write_data(unsigned			port_id_,
						 unsigned			current_burst_,
						 unsigned			rank_sel_,
						 unsigned			bank_sel_,
						 SDRAM_DDR_data_t	data_,
						 bool				direct_access_);

	const sc_logic
	SDRAM_DDR_get_DQS(unsigned	port_id_,
					  unsigned	rank_sel_,
					  unsigned	bank_sel_) const;

	const bool
	SDRAM_DDR_set_DQS(unsigned	port_id_,
					  unsigned	rank_sel_,
					  unsigned	bank_sel_,
					  sc_logic	DQS_);

	SC_HAS_PROCESS(SDRAM_DDR_DP_device);

	SDRAM_DDR_DP_device(sc_module_name	name_);

	SDRAM_DDR_DP_device(sc_module_name		name_,
						SDRAM_bitwidth_t	bit_width_module_,
						SDRAM_num_t			rank_num_,
						SDRAM_size_t		technology_,
						SDRAM_bitwidth_t	bit_width_comp_,
						unsigned			CL_,
						unsigned			tRCD_,
						unsigned			tRP_,
						unsigned			tWR_);

	~SDRAM_DDR_DP_device();

protected:
	SDRAM_bitwidth_t			ext_bitwidth_component;

	SDRAM_num_t					rank_num;
	SDRAM_num_t					component_per_rank_num;
	SDRAM_num_t					bank_num;
	SDRAM_num_t					row_num;
	SDRAM_num_t					column_num;

	unsigned					tRCD;
	unsigned					tRP;
	unsigned					tWR;

	byte*****					SDRAM_array_byte;
	unsigned short*****			SDRAM_array_halfword;
	unsigned*****				SDRAM_array_word;

	SDRAM_DDR_bank_state_t**	bank_state;	

	byte****					row_buffer_byte;
	unsigned short****			row_buffer_halfword;
	unsigned****				row_buffer_word;

	SDRAM_DDR_mode_register_t*	mode_register;

	sc_logic***					DQS;
	unsigned					port_request_cnt;

	byte****					output_buffer_byte;
	unsigned short****			output_buffer_halfword;
	unsigned****				output_buffer_word;

	bool***						read_commanded;
	sc_time***					read_commanded_time;
	bool***						write_finished;
	sc_time***					write_finished_time;

	void
	determine_nums(unsigned			tech_,
				   SDRAM_bitwidth_t	bitwidth_comp_);

	void
	generate_cells();

	void
	initialize_cells();

	void
	bank_count_action();

	void
	command_count_action();
};

#endif
